package com.yvnze.ydyp.common.interceptor;


import com.yvnze.ydyp.common.constant.AnswerConstant;
import com.yvnze.ydyp.common.constant.SysConstant;
import com.yvnze.ydyp.common.info.TokenInfo;
import com.yvnze.ydyp.common.info.UserInfo;
import com.yvnze.ydyp.common.service.TokenService;
import com.yvnze.ydyp.common.wrapper.ResultWrapper;
import com.yvnze.ydyp.util.JsonUtil;
import com.yvnze.ydyp.util.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author HaiPeng Wang
 * @date 2021/7/14 16:21
 * @Description:
 */

/**
 * 自定义一个拦截器的方式就是实现HandlerInterceptor
 * 和mvcconfigure 不同这里才是拦截器定义的地方，springmvc 只是将你的拦截器放到了容器里面而这里是定义
 * 相应的拦截器的属性包括在每一个controller 执行前进行还是在每一个controller 执行后进行等等类似的
 * 这里的话将token 的配置也在这里进行一个实现
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {


    @Autowired
    TokenService tokenService;

    /**
     * prehandle 就是在所有的请求在发送的服务器之后在数据处理前执行的方法
     * @param request
     * @param response
     * @param handler
     * @return
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

                                //将字符串与指定字符串对象进行比较不考虑大小写
        if (request.getMethod().equalsIgnoreCase("options")) {   //？为什么？
            return true;
        }
        String accessToken = null;
                                            //ANSWER_ACCESS_TOKEN
        accessToken = request.getHeader(AnswerConstant.HTTP_HEADER_ANSWER_ACCESS_TOKEN);

                                            //accessToken 如果token没放在请求头里面，可能是放在了表单里面传递，所以这里再配置一下表单传递的可能

        ResultWrapper resultWrapper = null;
        response.setHeader("Content-Type", "application/json;charset=utf-8");


        /**
         * 未传递Token
         */
        if (null == accessToken){
            ThreadLocalUtil.remove(SysConstant.THREAD_LOCAL_KEY_LOGIN_USER);
            System.out.println(request.getRequestURL() + "  LoginInterceptor.preHandle  未传递Token");
            resultWrapper = ResultWrapper.failure("未认证");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            try {
                response.getWriter().println(JsonUtil.toJson(resultWrapper));
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }
        /**
         * 接收到token,
         */
        TokenInfo tokenInfo = tokenService.getTokenInfo(accessToken);
        if (null == tokenInfo){
            /**
             * 错误的token
             */
            ThreadLocalUtil.remove(SysConstant.THREAD_LOCAL_KEY_LOGIN_USER);
            resultWrapper = ResultWrapper.failure("错误的Token");
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            try {
                response.getWriter().println(JsonUtil.toJson(resultWrapper));
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }

        /**
         * 正确的token，在redis中有这个token且没过期
         */
        tokenService.refreshToken(tokenInfo.getAccessToken(),tokenInfo.getUserId());
        /**
         * 将userInfo设置到ThreadLocal
         */
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(tokenInfo.getUserId());
        ThreadLocalUtil.put(SysConstant.THREAD_LOCAL_KEY_LOGIN_USER, userInfo);
        return true;
    }

}
